//
//  Chibi.m
//  iChibi
//
//  Created by Meng Zhang on 11-5-19.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "Chibi.h"

//main.c
#define main chibi_main
#include "../main.c"

char* sexp_default_module_path;

#define STDIN_READ    _in[0]
#define STDIN_WRITE   _in[1]
#define STDOUT_READ   _out[0]
#define STDOUT_WRITE  _out[1]

@interface Chibi()
- (void)readStdout:(NSNotification *)aNotify;
@end

@implementation Chibi

- (id)init 
{
  if ((self = [super init])) {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"init-7" ofType:@"scm" inDirectory:@"lib"];
    sexp_default_module_path = strdup([[path stringByDeletingLastPathComponent] cStringUsingEncoding:NSASCIIStringEncoding]);
    
    sexp_scheme_init();
    
    pipe(_in);
    pipe(_out);
    dup2(STDIN_READ, 0);
    dup2(STDOUT_WRITE, 1);
    dup2(STDOUT_WRITE, 2);
    
    _queue = dispatch_queue_create(NULL, 0);
    
    _outHandle = [[NSFileHandle alloc] initWithFileDescriptor:STDOUT_READ];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readStdout:) name:NSFileHandleReadCompletionNotification object:_outHandle];
  }
  return self;
}

- (void)dealloc 
{
  close(_in[0]);
  close(_in[1]);
  close(_out[0]);
  close(_out[1]);
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  
  dispatch_release(_queue);
  [_outHandle release];
  
  [super dealloc];
}

- (void)repl 
{
  dispatch_async(_queue, ^{
    char *argv = "ichibi";
    chibi_main(1, &argv);
  });
  [_outHandle readInBackgroundAndNotify];
}

- (void)sendChars:(NSString *)chars
{
  const char* c = [chars cStringUsingEncoding:NSASCIIStringEncoding];
  write(STDIN_WRITE, c, strlen(c));
  [_outHandle readInBackgroundAndNotify];
}

#pragma mark - Notification
- (void)readStdout:(NSNotification *)aNotify
{
  NSData *data = [[aNotify userInfo]
                  objectForKey:NSFileHandleNotificationDataItem];
  NSString *string = [[NSString alloc] initWithData:data
                                           encoding:NSASCIIStringEncoding];
  
  [[NSNotificationCenter defaultCenter] postNotificationName:CHIBI_UDPATE_NOTIFICATION 
                                                      object:self 
                                                    userInfo:[NSDictionary dictionaryWithObject:string forKey:@"content"]];
  [_outHandle readInBackgroundAndNotify];
  
  [string release];
}

@end
